//
//  JKImageDownloadManager.m
//  JackToolsBox
//
//  Created by Jack Xue on 2019/12/9.
//  Copyright © 2019 Jack Xue. All rights reserved.
//

/*
 2019.12.10 - 断点续传
 https://blog.csdn.net/menghuanhongye1987/article/details/11905781
 断点续传是在发起HTTP请求的时候加入RANGE头来告诉服务器客户端已经下载了多少字节
 ---服务器不一定支持断点续传---
 */

#import "JKImageDownloadManager.h"

@interface JKImageDownloadManager (){
    NSMutableDictionary *_taskDict;     //负责记录imageView-task
    NSMutableDictionary *_cacheDict;    //使用断点续传时取消该行注释
}
@end

@implementation JKImageDownloadManager
- (instancetype)init
{
    self = [super init];
    if (self) {
        _taskDict = [NSMutableDictionary dictionaryWithCapacity:20];
    }
    return self;
}

#pragma mark - 调整任务优先，放弃老任务
- (void)sendDownloadTask:(NSString *)task imageView:(NSString*)imageView withImage:(void(^)(UIImage *_Nullable image))imageblock fail:(void(^)(NSError* err))failure{
    //如果view发出新任务请求，取消老任务
    NSURLSessionDownloadTask *workingTask = [_taskDict valueForKey:imageView];
    if (workingTask) {
        //取消正在进行的老任务
        [workingTask cancel]; workingTask = nil;
    }
    
    //开始以view最后申请的下载任务，以view地址作为key记录
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:task]];
    NSURLSessionDownloadTask *loadTask = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //code == -999 ---> task cancled
        if (error && failure && error.code != -999) {
            //下载失败，回传原因
            failure(error);
        }
        if (!error && imageblock) {
            UIImage *result = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
            if (result) {
                imageblock(result);
            }
        }//@end - 判断block为空
    }];
    [loadTask resume];
    [_taskDict setValue:loadTask forKey:imageView];
    
}

#pragma mark - 调整任务优先（支持断点续传）
-(void)remainDownloadTask:(NSString *)task imageView:(NSString*)imageView mdImageKey:(NSString*)key withImage:(void(^)(UIImage *image))imageblock{
    //如果view发出新任务请求，暂停老任务
    NSURLSessionDownloadTask *workingTask = [_taskDict valueForKey:imageView];
    if (workingTask) {
        //暂停正在进行的任务,将下载进度保存
        [workingTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
            [self->_cacheDict setValue:resumeData forKey:key];
        }];
    }
    
    //根据url->md5处理后的字符串查找暂停的任务，可以断点续传
    NSData *conData = [_cacheDict valueForKey:key];
    if (conData) {
        NSURLSessionDownloadTask *continueTask = [[NSURLSession sharedSession]downloadTaskWithResumeData:conData completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if (!error && imageblock) {
                imageblock([UIImage imageWithData:[NSData dataWithContentsOfURL:location]]);
            }
        }];
        [continueTask resume];
        [_taskDict setValue:continueTask forKey:imageView];
    }else{
        //请求新任务，并进行标记
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:task]];
        NSURLSessionDownloadTask *loadTask = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if (!error && imageblock) {
                imageblock([UIImage imageWithData:[NSData dataWithContentsOfURL:location]]);
            }
        }];
        [loadTask resume];
        [_taskDict setValue:loadTask forKey:imageView];
    }
}


@end
